/**
 * 房间管理模块 - 管理公聊和私聊房间的完整数据结构
 */

// 房间类型枚举
const ROOM_TYPES = {
  PUBLIC: 'public',
  PRIVATE: 'private'
};

// 房间状态枚举
const ROOM_STATUS = {
  ACTIVE: 'active',
  INACTIVE: 'inactive',
  PAUSED: 'paused',
  CLOSED: 'closed'
};

// 私聊房间加入策略
const JOIN_POLICIES = {
  OWNER_APPROVAL: 'ownerApproval',  // 房主审批
  INVITE_ONLY: 'inviteOnly',        // 仅邀请
  OPEN: 'open'                      // 开放加入
};

/**
 * 基础房间类
 */
class BaseRoom {
  constructor(roomId, type, channelId) {
    this.roomId = roomId;
    this.type = type;
    this.channelId = channelId;
    this.status = ROOM_STATUS.ACTIVE;
    
    // 参与者管理
    this.participants = new Set();
    this.maxParticipants = type === ROOM_TYPES.PUBLIC ? 50 : 10;
    
    // 时间戳
    this.createdAt = new Date();
    this.lastActiveAt = new Date();
    
    // 房间设置
    this.settings = {
      allowSpectators: true,
      recordingEnabled: false,
      autoCleanup: true
    };
    
    // 统计信息
    this.stats = {
      totalJoined: 0,
      totalLeft: 0,
      peakParticipants: 0,
      totalDuration: 0
    };
  }

  /**
   * 添加参与者
   */
  addParticipant(userId) {
    if (this.participants.has(userId)) {
      return { success: false, reason: 'already_joined' };
    }
    
    if (this.participants.size >= this.maxParticipants) {
      return { success: false, reason: 'room_full' };
    }
    
    if (this.status !== ROOM_STATUS.ACTIVE) {
      return { success: false, reason: 'room_inactive' };
    }
    
    this.participants.add(userId);
    this.stats.totalJoined++;
    this.stats.peakParticipants = Math.max(this.stats.peakParticipants, this.participants.size);
    this.lastActiveAt = new Date();
    
    return { success: true };
  }

  /**
   * 移除参与者
   */
  removeParticipant(userId) {
    if (!this.participants.has(userId)) {
      return { success: false, reason: 'not_in_room' };
    }
    
    this.participants.delete(userId);
    this.stats.totalLeft++;
    this.lastActiveAt = new Date();
    
    return { success: true };
  }

  /**
   * 检查用户是否在房间中
   */
  hasParticipant(userId) {
    return this.participants.has(userId);
  }

  /**
   * 获取参与者列表
   */
  getParticipants() {
    return Array.from(this.participants);
  }

  /**
   * 获取参与者数量
   */
  getParticipantCount() {
    return this.participants.size;
  }

  /**
   * 更新房间状态
   */
  updateStatus(newStatus) {
    if (Object.values(ROOM_STATUS).includes(newStatus)) {
      this.status = newStatus;
      this.lastActiveAt = new Date();
      return true;
    }
    return false;
  }

  /**
   * 更新房间设置
   */
  updateSettings(newSettings) {
    this.settings = { ...this.settings, ...newSettings };
    this.lastActiveAt = new Date();
  }

  /**
   * 检查房间是否应该清理
   */
  shouldCleanup() {
    if (!this.settings.autoCleanup) return false;
    
    // 空房间超过5分钟自动清理
    if (this.participants.size === 0) {
      const inactiveTime = Date.now() - this.lastActiveAt.getTime();
      return inactiveTime > 5 * 60 * 1000; // 5分钟
    }
    
    return false;
  }

  /**
   * 获取房间摘要（用于广播）
   */
  getSummary() {
    return {
      roomId: this.roomId,
      type: this.type,
      channelId: this.channelId,
      status: this.status,
      participants: this.getParticipants(),
      participantCount: this.getParticipantCount(),
      maxParticipants: this.maxParticipants,
      createdAt: this.createdAt,
      lastActiveAt: this.lastActiveAt,
      settings: this.settings
    };
  }

  /**
   * 获取详细信息（用于管理）
   */
  getDetailedInfo() {
    return {
      ...this.getSummary(),
      stats: this.stats
    };
  }
}

/**
 * 公聊房间类
 */
class PublicRoom extends BaseRoom {
  constructor(channelId) {
    super(`public_${channelId}`, ROOM_TYPES.PUBLIC, channelId);
    
    // 公聊房间特有属性
    this.isDefault = true;
    this.autoStart = true;
    this.welcomeMessage = '欢迎加入公共语音聊天！';
    
    // 公聊房间设置
    this.settings = {
      ...this.settings,
      allowSpectators: true,
      muteNewJoiners: false,
      requireApproval: false
    };
  }

  /**
   * 公聊房间总是活跃的
   */
  updateStatus(newStatus) {
    // 公聊房间不能被关闭，只能暂停
    if (newStatus === ROOM_STATUS.CLOSED) {
      return super.updateStatus(ROOM_STATUS.PAUSED);
    }
    return super.updateStatus(newStatus);
  }

  /**
   * 公聊房间不需要清理
   */
  shouldCleanup() {
    return false;
  }
}

/**
 * 私聊房间类
 */
class PrivateRoom extends BaseRoom {
  constructor(roomId, channelId, ownerId) {
    super(roomId, ROOM_TYPES.PRIVATE, channelId);
    
    // 私聊房间特有属性
    this.ownerId = ownerId;
    this.joinPolicy = JOIN_POLICIES.OWNER_APPROVAL;
    
    // 邀请和申请管理
    this.pendingInvites = new Set();     // 待处理的邀请
    this.joinRequests = new Set();       // 加入申请
    this.bannedUsers = new Set();        // 被禁用户
    
    // 私聊房间设置
    this.maxParticipants = 8;
    this.settings = {
      ...this.settings,
      allowSpectators: false,
      requireOwnerPresence: true,
      autoCloseWhenOwnerLeaves: true
    };
    
    // 房主自动加入
    this.addParticipant(ownerId);
  }

  /**
   * 发送邀请
   */
  sendInvite(targetUserId) {
    if (this.participants.has(targetUserId)) {
      return { success: false, reason: 'already_in_room' };
    }
    
    if (this.bannedUsers.has(targetUserId)) {
      return { success: false, reason: 'user_banned' };
    }
    
    if (this.pendingInvites.has(targetUserId)) {
      return { success: false, reason: 'invite_pending' };
    }
    
    this.pendingInvites.add(targetUserId);
    this.lastActiveAt = new Date();
    
    return { success: true };
  }

  /**
   * 处理邀请回应
   */
  handleInviteResponse(userId, accepted) {
    if (!this.pendingInvites.has(userId)) {
      return { success: false, reason: 'no_pending_invite' };
    }
    
    this.pendingInvites.delete(userId);
    
    if (accepted) {
      return this.addParticipant(userId);
    }
    
    return { success: true, reason: 'invite_declined' };
  }

  /**
   * 申请加入
   */
  requestJoin(userId) {
    if (this.joinPolicy === JOIN_POLICIES.INVITE_ONLY) {
      return { success: false, reason: 'invite_only' };
    }
    
    if (this.participants.has(userId)) {
      return { success: false, reason: 'already_in_room' };
    }
    
    if (this.bannedUsers.has(userId)) {
      return { success: false, reason: 'user_banned' };
    }
    
    if (this.joinPolicy === JOIN_POLICIES.OPEN) {
      return this.addParticipant(userId);
    }
    
    // 需要房主审批
    if (this.joinRequests.has(userId)) {
      return { success: false, reason: 'request_pending' };
    }
    
    this.joinRequests.add(userId);
    this.lastActiveAt = new Date();
    
    return { success: true, reason: 'approval_required' };
  }

  /**
   * 处理加入申请
   */
  handleJoinRequest(userId, approved, approverId) {
    if (approverId !== this.ownerId) {
      return { success: false, reason: 'not_owner' };
    }
    
    if (!this.joinRequests.has(userId)) {
      return { success: false, reason: 'no_pending_request' };
    }
    
    this.joinRequests.delete(userId);
    
    if (approved) {
      return this.addParticipant(userId);
    }
    
    return { success: true, reason: 'request_denied' };
  }

  /**
   * 踢出用户
   */
  kickUser(userId, kickerId) {
    if (kickerId !== this.ownerId) {
      return { success: false, reason: 'not_owner' };
    }
    
    if (userId === this.ownerId) {
      return { success: false, reason: 'cannot_kick_owner' };
    }
    
    const result = this.removeParticipant(userId);
    if (result.success) {
      this.bannedUsers.add(userId);
    }
    
    return result;
  }

  /**
   * 转移房主
   */
  transferOwnership(newOwnerId, currentOwnerId) {
    if (currentOwnerId !== this.ownerId) {
      return { success: false, reason: 'not_current_owner' };
    }
    
    if (!this.participants.has(newOwnerId)) {
      return { success: false, reason: 'new_owner_not_in_room' };
    }
    
    this.ownerId = newOwnerId;
    this.lastActiveAt = new Date();
    
    return { success: true };
  }

  /**
   * 检查房间是否应该清理
   */
  shouldCleanup() {
    // 房主离开且设置了自动关闭
    if (this.settings.autoCloseWhenOwnerLeaves && !this.participants.has(this.ownerId)) {
      return true;
    }
    
    return super.shouldCleanup();
  }

  /**
   * 获取房间摘要
   */
  getSummary() {
    return {
      ...super.getSummary(),
      ownerId: this.ownerId,
      joinPolicy: this.joinPolicy,
      pendingInvites: Array.from(this.pendingInvites),
      joinRequests: Array.from(this.joinRequests),
      bannedUsers: Array.from(this.bannedUsers)
    };
  }
}

/**
 * 频道房间管理器
 */
class ChannelRoomManager {
  constructor(channelId) {
    this.channelId = channelId;
    this.publicRoom = new PublicRoom(channelId);
    this.privateRooms = new Map(); // roomId -> PrivateRoom
    this.createdAt = new Date();
  }

  /**
   * 获取公聊房间
   */
  getPublicRoom() {
    return this.publicRoom;
  }

  /**
   * 创建私聊房间
   */
  createPrivateRoom(ownerId) {
    const roomId = `private_${this.channelId}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
    const room = new PrivateRoom(roomId, this.channelId, ownerId);
    this.privateRooms.set(roomId, room);
    return room;
  }

  /**
   * 获取私聊房间
   */
  getPrivateRoom(roomId) {
    return this.privateRooms.get(roomId);
  }

  /**
   * 获取所有活跃的私聊房间
   */
  getActivePrivateRooms() {
    const activeRooms = [];
    this.privateRooms.forEach((room, roomId) => {
      if (room.status === ROOM_STATUS.ACTIVE) {
        activeRooms.push(room);
      }
    });
    return activeRooms;
  }

  /**
   * 获取用户所在的房间
   */
  getUserRooms(userId) {
    const rooms = [];
    
    // 检查公聊
    if (this.publicRoom.hasParticipant(userId)) {
      rooms.push(this.publicRoom);
    }
    
    // 检查私聊
    this.privateRooms.forEach((room) => {
      if (room.hasParticipant(userId)) {
        rooms.push(room);
      }
    });
    
    return rooms;
  }

  /**
   * 清理过期房间
   */
  cleanupRooms() {
    const toDelete = [];
    
    this.privateRooms.forEach((room, roomId) => {
      if (room.shouldCleanup()) {
        toDelete.push(roomId);
      }
    });
    
    toDelete.forEach(roomId => {
      console.log(`清理过期房间: ${roomId}`);
      this.privateRooms.delete(roomId);
    });
    
    return toDelete;
  }

  /**
   * 获取房间统计信息
   */
  getStats() {
    const stats = {
      channelId: this.channelId,
      publicRoom: this.publicRoom.getDetailedInfo(),
      privateRooms: {
        total: this.privateRooms.size,
        active: this.getActivePrivateRooms().length,
        rooms: []
      },
      createdAt: this.createdAt
    };
    
    this.privateRooms.forEach((room) => {
      stats.privateRooms.rooms.push(room.getSummary());
    });
    
    return stats;
  }

  /**
   * 获取房间列表摘要（用于广播）
   */
  getRoomsSummary() {
    return {
      channelId: this.channelId,
      publicRoom: this.publicRoom.getSummary(),
      privateRooms: Array.from(this.privateRooms.values()).map(room => room.getSummary()),
      createdAt: this.createdAt
    };
  }
}

/**
 * 全局房间管理器
 */
class GlobalRoomManager {
  constructor() {
    this.channels = new Map(); // channelId -> ChannelRoomManager
    this.cleanupInterval = null;
    
    // 启动定期清理
    this.startCleanupTimer();
  }

  /**
   * 获取或创建频道房间管理器
   */
  getChannelManager(channelId) {
    if (!this.channels.has(channelId)) {
      this.channels.set(channelId, new ChannelRoomManager(channelId));
    }
    return this.channels.get(channelId);
  }

  /**
   * 移除频道
   */
  removeChannel(channelId) {
    this.channels.delete(channelId);
  }

  /**
   * 启动清理定时器
   */
  startCleanupTimer() {
    this.cleanupInterval = setInterval(() => {
      this.channels.forEach((channelManager, channelId) => {
        const cleanedRooms = channelManager.cleanupRooms();
        if (cleanedRooms.length > 0) {
          console.log(`频道 ${channelId} 清理了 ${cleanedRooms.length} 个过期房间`);
        }
      });
    }, 60000); // 每分钟清理一次
  }

  /**
   * 停止清理定时器
   */
  stopCleanupTimer() {
    if (this.cleanupInterval) {
      clearInterval(this.cleanupInterval);
      this.cleanupInterval = null;
    }
  }

  /**
   * 获取全局统计信息
   */
  getGlobalStats() {
    let totalPublicParticipants = 0;
    let totalPrivateRooms = 0;
    let totalPrivateParticipants = 0;
    
    const channelStats = [];
    
    this.channels.forEach((channelManager, channelId) => {
      const stats = channelManager.getStats();
      channelStats.push(stats);
      
      totalPublicParticipants += stats.publicRoom.participantCount;
      totalPrivateRooms += stats.privateRooms.total;
      
      stats.privateRooms.rooms.forEach(room => {
        totalPrivateParticipants += room.participantCount;
      });
    });
    
    return {
      totalChannels: this.channels.size,
      totalPublicParticipants,
      totalPrivateRooms,
      totalPrivateParticipants,
      channels: channelStats
    };
  }
}

module.exports = {
  ROOM_TYPES,
  ROOM_STATUS,
  JOIN_POLICIES,
  BaseRoom,
  PublicRoom,
  PrivateRoom,
  ChannelRoomManager,
  GlobalRoomManager
};